#include "inventaire.h"
#include "graphics.opengl/renderer.h"
#include "graphics/graphicsmanager.h"

#include "worldgridmanager.h"
#include "application.h"



namespace infinity {
	namespace render {

Inventaire::Inventaire(Container* container)
:	m_vertexFormat(NULL)
,	m_indexBuffer(NULL)
,	m_vertexBuffer(NULL)
,	m_root(NULL)
,	m_container(container)
,	m_trianglesCount(0)
{
	dwAssert(m_container != NULL, "Invalid container");
}

Inventaire::~Inventaire()
{
	dw::graphics::Renderer& renderer = dw::graphics::GraphicsManager::getInstance().getRenderer();

	renderer.releaseIndexBuffer(m_indexBuffer);
	renderer.releaseVertexBuffer(m_vertexBuffer);

	delete m_vertexFormat;
	delete m_root;
}


void Inventaire::initializeGUI()
{
	const dw::system::Window& window = Application::getInstance().getWindow();

	RECT rect;								
	GetClientRect (window.getHandle(),&rect);		

	dw::maths::Vector2f backTextSize = dw::maths::Vector2f(((COLUMN*DIMENSIONSLOT_INV)+(COLUMN+1)*OFFSETSLOT_INV),((ROW*DIMENSIONSLOT_INV)+(ROW+1)*OFFSETSLOT_INV));

	float offsetx = (rect.right - backTextSize.x)/2;
	float offsety = (rect.bottom - backTextSize.y)/2;

	m_root = new Widget();
	m_root->setPosition(dw::maths::Vector2f(offsetx,offsety));

	unsigned int index = 0;
	for(unsigned int x = 0 ; x < ROW ; ++x)
	{
		for(unsigned int y = 0 ; y < COLUMN ; ++y)
		{
			index = y + (x*ROW);
			m_imagesBoxes[index].setPosition(dw::maths::Vector2f(0.0f,0.0f));
			m_imagesBoxes[index].setDimension(dw::maths::Vector2f(DIMENSIONSLOT_INV,DIMENSIONSLOT_INV));
			m_imagesBoxes[index].setImageUV(dw::maths::Vector2f(0.0f,0.0f),dw::maths::Vector2f(0.0f,0.0f));
			m_imagesBoxes[index].setZOrder(Widget::LAYER_FRONT);

			m_root->addChild(& m_imagesBoxes[index]);
		}
	}

	m_backText.setPosition(dw::maths::Vector2f(0.0f,0.0f));
	m_backText.setDimension(backTextSize);
	m_backText.setImageUV(dw::maths::Vector2f(0.0f,6.0f/16.0f),dw::maths::Vector2f(1.0f/16.0f,7.0f/16.0f));
	m_backText.setZOrder(Widget::LAYER_BACK);

	m_root->addChild(& m_backText);

	createMesh();
}

void Inventaire::createMesh()
{
	dw::graphics::Renderer& renderer = dw::graphics::GraphicsManager::getInstance().getRenderer();

	using dw::graphics::VertexElement;

	static const VertexElement elements[] = {
		{ VertexElement::vec3, VertexElement::position, 0 },
		{ VertexElement::vec2, VertexElement::texcoord, 0 }
	};

	m_vertexFormat = new dw::graphics::VertexFormat(elements, 2);

	m_indexBuffer = renderer.createIndexBuffer(
		dw::graphics::IndexBuffer::update_often,
		dw::graphics::IndexBuffer::uint16);

	m_indexBuffer->bind();
	m_indexBuffer->resize((NBSLOT_INV + 1) * 6);
	m_indexBuffer->unbind();

	m_vertexBuffer = renderer.createVertexBuffer(
		dw::graphics::VertexBuffer::update_often,
		m_vertexFormat);

	m_vertexBuffer->bind();
	m_vertexBuffer->resize((NBSLOT_INV+1) * 4);
	m_vertexBuffer->unbind();

	updateBuffer();
}


void Inventaire::updateGUI()
{
	const WorldGridManager& worldManager = WorldGridManager::getInstance();
	const MaterialLibrary& materialLib = worldManager.getPlanet()->getMaterialLibrary();
	const ItemMaterialLibrary& itemmaterialLib = worldManager.getPlanet()->getItemMaterialLibrary();

	dw::maths::Vector2f texcoord;
	
	m_root->deleteChildren();
	
	unsigned int index = 0;
	for(unsigned int x = 0 ; x < ROW ; ++x)
	{
		for(unsigned int y = 0 ; y < COLUMN ; ++y)
		{
			index = y + (x*COLUMN);
			
			Container::Slot slot = m_container->getSlot(index);
			m_imagesBoxes[index].setPosition(dw::maths::Vector2f(y * (DIMENSIONSLOT_INV + OFFSETSLOT_INV) + OFFSETSLOT_INV,((ROW-1)-x) * (DIMENSIONSLOT_INV + OFFSETSLOT_INV)  + OFFSETSLOT_INV));
			m_imagesBoxes[index].setDimension(dw::maths::Vector2f(DIMENSIONSLOT_INV,DIMENSIONSLOT_INV));

			if(slot.object.type == Object::BLOC || slot.object.type == Object::ENTITY_BLOC)
			{
				const Material& material = materialLib.getMaterialFromId(slot.object.id);
				texcoord = material.getOffsetTop();

				m_imagesBoxes[index].setImageUV(texcoord,dw::maths::Vector2f(texcoord.x + 1.0f/16.0f, texcoord.y + 1.0f/16.0f));
			}
			else if(slot.object.type == Object::ENTITY)
			{
				m_imagesBoxes[index].setImageUV(dw::maths::Vector2f( 2.0/16.0f, 7.0/16.0f),dw::maths::Vector2f( 3.0/16.0f, 8.0/16.0f));
			}
			else
			{
				m_imagesBoxes[index].setImageUV(dw::maths::Vector2f( 11.0/16.0f, 0.0),dw::maths::Vector2f( 12.0f/16.0f,  1.0f/16.0f));
			}
			
			m_root->addChild(& m_imagesBoxes[index]);
		}
	}

	m_root->addChild(&m_backText);

	updateBuffer();
}


void Inventaire::updateBuffer()
{
	std::vector<Widget::UiVertex> vertex;
	std::vector<dw::uint16> index;

	m_trianglesCount = m_root->collectGeometry(&vertex,&index);	

	{
		m_indexBuffer->bind();
		m_indexBuffer->write(&index[0]);
		m_indexBuffer->unbind();

		m_vertexBuffer->bind();
		m_vertexBuffer->write(&vertex[0]);
		m_vertexBuffer->unbind();
	}	
}
		

	}//namespace render
} // namespace infinity
